<template>
	<view class="ble_connect_wrap">
		<view class="header">
			<view class="content">
				<view class="blue_tooth_connect_box">
					<image v-show="isConnectDevie" class="icon" src="@/static/image/bluetooth.png"
						alt="" />
					<image v-show="!isConnectDevie" class="icon" src="@/static/image/bluetooth_not.png"
						alt="" />
					<text class="text">{{ isConnectDevie?'已连接':'未连接' }}</text>
				</view>
			</view>
		</view>
		<view class="main">
			<text class="title">已搜索到的设备</text>
			<view class="content">
				<view class="dev_list_box">
					<view class="dev_item_box" v-for="(dl,indexD) in deviceList">
						<image class="icon" src="@/static/image/bluetooth_samll.png" alt="" srcset="" />
						<text class="device_name">{{ dl.name }}</text>
						<uv-button v-if="!dl.isConnect" type="primary" class="action_button"
							@click="connectClick(dl)">连接</uv-button>
						<uv-button v-else type="error" class="action_button" @click="breakClick(dl)">断开</uv-button>
					</view>
					<uv-empty v-if="deviceList.length == 0" text="未找到相关蓝牙设备" mode="search"
						icon="https://cdn.uviewui.com/uview/empty/search.png"></uv-empty>
				</view>
			</view>
		</view>
	</view>
</template>
<script>
	import {
		matchedMessageErrorMsg
	} from '@/static/bluetooth_errorMsg.js'

	export default {
		name: 'blueToothTestPage',
		data() {
			return {
				// 手机是否开启蓝牙
				IsBluetoothOpen: '',

				// 是否初始化蓝牙
				IsInitBluetooth: '',

				// 蓝牙返回错误信息
				errorMsg: '--',

				// 设备列表
				deviceList: [],

				// 设备服务列表
				deviceServiceList: [],

				// 设备服务特征值列表
				deviceServiceCharacteristicList: [],

				// 当前状态code
				currentStatusCode: '2000',

				// 是否已连接蓝牙设备
				isConnectDevie: false,

				// 当前连接的设备信息
				currentConnectDeviceInfo: {},

				// 收到的数据列表
				receptionDataList: [

				],

				// 状态列表
				statusList: [{
						code: '2000',
						message: '等待中'
					},
					{
						code: '2001',
						message: '打开蓝牙成功'
					},
					{
						code: '2002',
						message: '初始化蓝牙成功'
					},
					{
						code: '2003',
						message: '已找到设备'
					},
					{
						code: '2004',
						message: '蓝牙设备已连接'
					},
					{
						code: '2005',
						message: '蓝牙设备连接失败'
					},
					{
						code: '2006',
						message: '获取蓝牙所有服务成功'
					},
					{
						code: '2007',
						message: '获取蓝牙所有服务失败'
					},
					{
						code: '2008',
						message: '获取蓝牙某个服务的特征值成功'
					},
					{
						code: '2009',
						message: '获取蓝牙某个服务的特征值失败'
					}
				],
				sendData: ''
			}
		},
		computed: {
			// 当前状态
			currentStatus() {
				let statusMsg = ''
				this.statusList.forEach((item) => {
					if (item.code == this.currentStatusCode) {
						statusMsg = item.message
					}
				})
				return statusMsg
			}
		},
		methods: {
			// 连接的点击事件
			connectClick(item) {
				uni.showLoading({
					title: '正在连接',
					mark: true
				})
				this.createBluetoothConnection(item.deviceId)
			},
			// 断开的点击事件
			breakClick(item) {
				uni.showLoading({
					title: '正在断开',
					mark: true
				})
				this.closeBLEConnection(item.deviceId)
			},
			// 修改状态的方法
			setStatus(code) {
				this.currentStatusCode = code
			},
			// 打开手机蓝牙
			openPhoneBluetooth() {
				var main, BluetoothAdapter, BAdapter
				switch (uni.getSystemInfoSync().platform) {
					case 'android':
						// Android平台:
						main = plus.android.runtimeMainActivity()
						BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter')
						BAdapter = BluetoothAdapter.getDefaultAdapter()
						if (!BAdapter.isEnabled()) {
							this.IsBluetoothOpen = BAdapter.enable()
						} else {
							this.IsBluetoothOpen = BAdapter.enable()
						}

						console.log(this.IsBluetoothOpen)
						uni.setStorageSync('IsBluetoothOpen', this.IsBluetoothOpen)
						if (this.IsBluetoothOpen) {
							// initBlue
							this.initBlueTooth()
						}
						break

					case 'ios':
						// IOS 平台
						console.log('运行在IOS')
						break

					default:
						// 其他平台
						console.log('运行在其他平台')
						break
				}
			},

			// 初始化蓝牙
			initBlueTooth() {
				// 加载提示
				uni.showLoading({
					title: '初始化蓝牙中'
				});
				uni.openBluetoothAdapter({
					success: () => {
						console.log('初始化蓝牙成功')
						this.setStatus('2002')
						this.searchNearbyDevice()
						// 关闭加载
						uni.hideLoading();
					},
					fail: () => {
						console.log('初始化蓝牙失败')
					}
				})
			},

			// 搜索附近设备
			searchNearbyDevice() {
				uni.startBluetoothDevicesDiscovery({
					success: (res) => {
						let errMsgInfo = res.errMsg.split(':')[1]
						console.log('data', errMsgInfo)
						this.errorMsg = matchedMessageErrorMsg(errMsgInfo)

						// 寻找新设备
						this.findNewEquipment()
					}
				})
			},

			// 监听寻找到新设备的事件
			findNewEquipment() {
				// 加载动画
				uni.showLoading({
					title: '搜索设备中',
					mask: true
				});
// this.deviceList = []
				
				// console.log('111',111);
				uni.onBluetoothDeviceFound((res) => {
					// console.log('this',this);
					setTimeout(() => {
						uni.hideLoading()
					}, 2000)
					// console.log('res',res);
					// 如果存在 Lohand 字样
				// 	res.devices.push( {
    //     "deviceId": "DC:BD:CC:B1:D4:85",
    //     "name": "Lohand_BLE1",
    //     "RSSI": -35,
    //     "localName": "Lohand_BLE1",
    //     "advertisServiceUUIDs": []
    // })
					res.devices.forEach((item) => {
						if (item.name.indexOf('Lohand') != -1) {
							this.setStatus('2003')
							// 将设备添加到 deviceList 中
							console.log(res.devices)
							item.isConnect = false
							this.deviceList.push(item)


							// 找到蓝牙之后连接
							// this.createBluetoothConnection()
						}
					})
				})
			},

			// 连接蓝牙
			createBluetoothConnection(id) {
				console.log('准备连接')
				let deviceId = id
				// return Promise((resolve, reject) => {
				uni.createBLEConnection({
					deviceId: deviceId,
					success: async (res) => {
						this.setStatus('2004')
						console.log('res', res)
						// 改变状态
						this.isConnectDevie = true
						this.deviceList.forEach((item) => {
							if (item.deviceId == deviceId) {
								item.isConnect = true
								this.currentConnectDeviceInfo = item
							}
						})
						
						// 启动监听低功耗蓝牙设备连接状态
						this.onBLEConnectionStateChange()

			    	uni.hideLoading()
						// 连接成功提示
						uni.showToast({
							title: '连接成功',
							icon: 'success',
							duration: 2000
						})
						
						// 停止搜索附近设备
						// this.stopBluetoothDevicesDiscovery()
						
						
						// 获取蓝牙设备的所有服务
						this.getAllService()
		

						uni.navigateTo({
							url: '/pages/index/index'
						})

					},
					fail: (err) => {
						console.log('err', err)
						this.setStatus('2005')
					},
					complete: (info) => {
						console.log('info', info)
					}
					// })
				})
			},

			// 断开与蓝牙设备连接
			closeBLEConnection(id) {
				console.log('this.deviceList', this.deviceList);
				let _this = this
				let deviceId = id
				uni.closeBLEConnection({
					deviceId: deviceId,
					success() {
						console.log('断开成功!');
						// 改变状态
						_this.isConnectDevie = false
						_this.deviceList.forEach((item) => {
							if (item.deviceId == deviceId) {
								item.isConnect = false
							}
						})
						_this.currentConnectDeviceInfo = {}
						uni.showToast({
							title: '断开成功',
							icon: 'fail',
							duration: 1000
						})
						
						// 断开与设备的连接之后，再次开启搜索附近设备的功能
						// _this.searchNearbyDevice()

					},
					fail: () => {
						console.log('断开失败!');
					}
				})
			},

			// 获取蓝牙设备所有服务
			getAllService() {
				setTimeout(() => {
					uni.getBLEDeviceServices({
						deviceId: this.currentConnectDeviceInfo.deviceId,
						success: (res) => {
							console.log('获取蓝牙设备所有服务res', res)
							this.deviceServiceList = res.services
							this.setStatus('2006')

							// 获取服务当中的特征值
							this.getCharacteristic()
						},
						fail: (err) => {
							console.log('获取蓝牙设备所有服务error', error)
							this.setStatus('2007')
						}
					})
				}, 1000)
			},

			// 获取蓝牙设备服务中的特征值
			getCharacteristic() {
				setTimeout(() => {
					uni.getBLEDeviceCharacteristics({
						deviceId: this.currentConnectDeviceInfo.deviceId,
						serviceId: this.deviceServiceList[2].uuid,
						success: (res) => {
							console.log('获取蓝牙设备服务特征值res', res)
							this.deviceServiceCharacteristicList = res.characteristics
							this.setStatus('2008')

							// 订阅特征值
							this.notifyBLECharacteristicValueChange()
						},
						fail: (err) => {
							console.log('获取蓝牙设备服务特征值err', err)
							this.setStatus('2009')
						}
					})
				}, 1000)
			},

			// 订阅特征值
			notifyBLECharacteristicValueChange() {
				console.log('准备订阅特征值')
				setTimeout(() => {
					let devieId = this.currentConnectDeviceInfo.deviceId
					let serviceId = this.deviceServiceList[2].uuid
					let characteristicId = this.deviceServiceCharacteristicList[1].uuid
					uni.notifyBLECharacteristicValueChange({
						state: true,
						deviceId: devieId,
						serviceId: serviceId,
						characteristicId: characteristicId,
						success: (res) => {
							console.log('订阅特征值res', res)
						},
						fail: (err) => {
							console.log('订阅特征值err', err)
						},
						complete: (err) => {
							this.onBLECharacteristicValueChange()
						}
					})
				}, 1000)
			},

			//监听设备发送过来的数据
			onBLECharacteristicValueChange() {
				console.log('准备接收数据')
				uni.onBLECharacteristicValueChange((res) => {
					console.log('收到设备发送的数据', res)
					let hex16Value = this.ab2hex(res.value)
					let strValue = this.hexToString(hex16Value)
					console.log('收到的value的16进制数据为', hex16Value)
					console.log('收到的value的字符串数据为', strValue)
					this.receptionDataList.push(strValue)
				})
			},

			// 向蓝牙设备写入二进制数据
			writeBLECharacteristicValue(data) {
				let msg = this.sendData
				const buffer = new ArrayBuffer(msg.length)
				const dataView = new DataView(buffer)
				console.log(msg)
				for (var i = 0; i < msg.length; i++) {
					dataView.setUint8(i, msg.charAt(i).charCodeAt())
				}

				let dataW = {
					deviceId: this.deviceList[0].deviceId,
					serviceId: this.deviceServiceList[2].uuid,
					characteristicId: this.deviceServiceCharacteristicList[1].uuid,
					writeType: 'writeNoResponse',
					value: buffer
				}
				console.log('发送数据：', dataW.value)
				uni.writeBLECharacteristicValue({
					deviceId: dataW.deviceId,
					serviceId: dataW.serviceId,
					characteristicId: dataW.characteristicId,
					writeType: dataW.writeType,
					value: dataW.value,
					success: (res) => {
						console.log('向蓝牙设备写入数据res', res)
					},
					fail: (err) => {
						console.log('向蓝牙设备写入数据err', err)
					}
				})
			},

			// 监听低功耗蓝牙的连接状态的改变事件
			onBLEConnectionStateChange() {
				uni.onBLEConnectionStateChange((res) => {
					// 该方法回调中可以用于处理连接意外断开等异常情况
					console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
				})
			},
			
			// 停止搜寻附近的蓝牙设备
			stopBluetoothDevicesDiscovery(){
				uni.stopBluetoothDevicesDiscovery({
					success: () => {
						console.log('停止搜索设备功能成功');
					},
					fail: () => {
						console.log('停止搜索设备功能失败');
					}
				})
			},
			ab2hex(buffer) {
				console.log('转换前', buffer)
				const hexArr = Array.prototype.map.call(new Uint8Array(buffer), function(bit) {
					return ('00' + bit.toString(16)).slice(-2)
				})
				return hexArr.join('')
			},
			hexToString(hex) {
				var result = ''
				for (var i = 0; i < hex.length; i += 2) {
					result += String.fromCharCode(parseInt(hex.substr(i, 2), 16))
				}
				return result
			}
		},
		created() {
			this.openPhoneBluetooth()
		}
	}
</script>
<style>
	.ble_connect_wrap {
		width: 100vw;
		height: calc(100vh);
		box-sizing: border-box;
		background: #f3f3f3;

		.header {
			width: 100vw;
			height: 26%;
			padding: 18px 16px 0px 16px;
			box-sizing: border-box;
			/* position: relative; */
			/* border: 1px solid red; */


			.content {
				width: 100%;
				height: 100%;
				/* background-color: white; */
				/* border: 1px solid red; */
				border-radius: 4px;
				margin: 0 auto;
				position: relative;
/* 				box-shadow:
					2px 2px 4px #d1d1d1; */
				/* -2px -2px 4px #d1d1d1; */


				.blue_tooth_connect_box {
					position: absolute;
					top: 50%;
					left: 50%;
					transform: translate(-50%, -50%);
					display: flex;
					flex-direction: column;
					text-align: center;


					.icon {
						width: 80px;
						height: 80px;
						position: relative;
						left: 50%;
						transform: translateX(-50%);
						margin-bottom: 16px;
						transition: 0.5s;
					}

					.text {
						font-size: 20px;
						font-weight: bold;
						letter-spacing: 1px;
					}
				}
			}
		}

		.main {
			/* border: 1px solid red; */
			width: 100vw;
			height: 74%;
			box-sizing: border-box;
			padding: 0px 16px 16px 16px;

			.title {
				display: inline-block;
				margin-bottom: 10px;
				font-size: 12px;
				color: #8b8b8b;
				/* border: 1px solid red; */
			}

			.content {
				height: 95%;
				background-color: white;
				border-radius: 4px;
				box-shadow:
					2px 2px 4px #d1d1d1;

				.dev_list_box {
					height: 100%;
					/* border: 1px solid red; */
					box-sizing: border-box;
					overflow-y: auto;

					.dev_item_box {
						/* border: 1px solid red; */
						border-top: 1px solid #f1f1ff;
						display: flex;
						flex-direction: row;
						height: 40px;
						line-height: 40px;
						position: relative;
						padding: 4px 2px 0px 6px;


						.icon {
							width: 30px;
							height: 30px;
							/* border: 1px solid red; */
							position: relative;
							top: 4px;
						}

						.action_button {
							height: 26px;
							position: absolute;
							right: 10px;
							top: 10px;
							letter-spacing: 2px;
						}

					}
				}
			}
		}
	}
</style>